#include "lcd-api.h"
#include "../gpio/gpio.h"
#include "../timer/timer32.h"

//#define uint32_t unsigned int

//#define uchar unsigned char

//======= IO setting =======//
#if 0
sbit Cs	    =P3^0;
sbit Reset  =P3^1;
sbit Dc     =P3^3;
sbit Wr     =P3^4;
sbit Rd		=P3^5;
#endif

void init_LCD(void);
void Display(uint16_t c1,uint16_t x,uint16_t y);
void Trans_Com_16(uint16_t data1);
void Trans_Dat_16(uint16_t data1);
void Delayms(uint16_t i);
void Delay(uint16_t i);



//=============================//
//======LCD Display Start======//
//=============================//
#if 0
void main(void)
 {
    uchar i,temp;
  	init_LCD();
   	while(1)
    {
		Display(colorc[temp],240,320);
		Delay(20);
		i++;
                temp=i%9;
     }
 }
#endif

//=== Output LCD data port ===//
void Write_Port_LCD(uint16_t data)
{
#if 0
	    uint16_t i;

	    for(i=LCD_DATA_LOW_PORT_LSB;i<(LCD_DATA_LOW_PORT_MSB+1);i++)
	    {
	    	/*Write data to LCD Low Port*/
	    	int value= ((data & (1 << i))>>i);
	    	GPIOSetValue( LCD_DATA_LOW_PORT,i,value);
	    }
#endif
	    LPC_GPIO[LCD_DATA_LOW_PORT]->DATA=data;
#if 0
	    for(i=LCD_DATA_HIGH_PORT_LSB;i<(LCD_DATA_HIGH_PORT_MSB+1);i++)
	    {
	    	/*Write data to LCD Low Port*/
	    	int value= ((data & (1 << (12+i)))>>(i+12));
	    	GPIOSetValue( LCD_DATA_HIGH_PORT,i,value);
	    }
#endif

	    LPC_GPIO[LCD_DATA_HIGH_PORT]->DATA = LPC_GPIO[LCD_DATA_HIGH_PORT]->DATA | (0x000F & (data>>12));
}

//=== Write reg. command ===//
void Trans_Com_16(uint16_t data1)
{
	//0=16bit; 1=8bit
	//uint16_t  high8=data1;
	//uint16_t  low8=data1;
 	//Cs=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_CS, PIN_OFF );
 	//Dc=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RS, PIN_OFF );
	//Rd=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RD, PIN_ON );


	//Wr=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_ON );
	//P1=high8;
	//Write_Port_LCD(high8);
	Write_Port_LCD(data1);
	//Wr=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_OFF );

	//Wr=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_ON);
	//P1=low8;
	//Write_Port_LCD(low8);
	//Wr=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_OFF );

	//Wr=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_ON);
	//Rd=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RD, PIN_OFF);
	//Dc=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RS, PIN_ON );
	//Cs=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_CS, PIN_ON);

}

//=== Write reg. data ===//
void Trans_Dat_16(uint16_t data1)
{
	//uint16_t  high8= data1;
	//uint16_t  low8=data1;
	//Cs=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_CS, PIN_OFF );
 	//Dc=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RS, PIN_ON );
	//Rd=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RD, PIN_ON );


	//Wr=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_ON );
	//P2=high8;
	//Write_Port_LCD(high8);
	Write_Port_LCD(data1);
	//Wr=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_OFF );

	//Wr=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_ON );
	//P1=low8;
	//Write_Port_LCD(low8);
	//Wr=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_OFF );

	//Wr=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_WR, PIN_ON );
	//Rd=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RD, PIN_OFF );
	//Dc=0;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_RS, PIN_OFF );
	//Cs=1;
	GPIOSetValue( LCD_CONTROL_PORT, LCD_CS, PIN_ON );

}

//=== LCD initial progress ===//
void init_LCD(void)
{

#if 0
	Reset=1;
	Delayms(1);
	Reset=0;
	Delayms(5);
	Reset=1;
	Delayms(10);
#endif

	//OTM3225A-C + HYDIS 2.4"QVGA
	//VCC 2.8V
	Trans_Com_16(0x00E3); Trans_Dat_16(0x3008); // Set internal timing
	Trans_Com_16(0x00E7); Trans_Dat_16(0x0012); // Set internal timing
	Trans_Com_16(0x00EF); Trans_Dat_16(0x1231); // Set internal timing
	Trans_Com_16(0x0001); Trans_Dat_16(0x0100); // set SS and SM bit
	Trans_Com_16(0x0002); Trans_Dat_16(0x0700); // set 1 line inversion
	Trans_Com_16(0x0003); Trans_Dat_16(0x1030); // set GRAM write direction and BGR=1.
	Trans_Com_16(0x0004); Trans_Dat_16(0x0000); // Resize register
	Trans_Com_16(0x0008); Trans_Dat_16(0x0207); // set the back porch and front porch
	Trans_Com_16(0x0009); Trans_Dat_16(0x0000); // set non-display area refresh cycle ISC[3:0]
	Trans_Com_16(0x000A); Trans_Dat_16(0x0000); // FMARK function
	Trans_Com_16(0x000C); Trans_Dat_16(0x0000); // RGB interface setting
	Trans_Com_16(0x000D); Trans_Dat_16(0x0000); // Frame marker Position
	Trans_Com_16(0x000F); Trans_Dat_16(0x0000); // RGB interface polarity
	//--------------Power On sequence --------------//
	Trans_Com_16(0x0010); Trans_Dat_16(0x0000); // SAP); Trans_Dat_16(BT[3:0]); Trans_Dat_16(AP); Trans_Dat_16(DSTB); Trans_Dat_16(SLP); Trans_Dat_16(STB
	Trans_Com_16(0x0011); Trans_Dat_16(0x0007); // DC1[2:0]); Trans_Dat_16(DC0[2:0]); Trans_Dat_16(VC[2:0]
	Trans_Com_16(0x0012); Trans_Dat_16(0x0000); // VREG1OUT voltage
	Trans_Com_16(0x0013); Trans_Dat_16(0x0000); // VDV[4:0] for VCOM amplitude
	Delayms(200); // Dis-charge capacitor power voltage
	Trans_Com_16(0x0010); Trans_Dat_16(0x1490); // SAP); Trans_Dat_16(BT[3:0]); Trans_Dat_16(AP); Trans_Dat_16(DSTB); Trans_Dat_16(SLP); Trans_Dat_16(STB
	Trans_Com_16(0x0011); Trans_Dat_16(0x0227); // R11h=0x0221 at VCI=3.3V); Trans_Dat_16(DC1[2:0]); Trans_Dat_16(DC0[2:0]); Trans_Dat_16(VC[2:0]
	Delayms(50); // Delayms 50ms
	Trans_Com_16(0x0012); Trans_Dat_16(0x001c); // External reference voltage= Vci;
	Delayms(50); // Delayms 50ms
	Trans_Com_16(0x0013); Trans_Dat_16(0x0A00); // R13=0F00 when R12=009E;VDV[4:0] for VCOM amplitude
	Trans_Com_16(0x0029); Trans_Dat_16(0x000F); // R29=0019 when R12=009E;VCM[5:0] for VCOMH//0012//
	Trans_Com_16(0x002B); Trans_Dat_16(0x000D); // Frame Rate = 91Hz
	Delayms(50); // Delayms 50ms
	Trans_Com_16(0x0020); Trans_Dat_16(0x0000); // GRAM horizontal Address
	Trans_Com_16(0x0021); Trans_Dat_16(0x0000); // GRAM Vertical Address
	// ----------- Adjust the Gamma Curve ----------//
	Trans_Com_16(0x0030); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0031); Trans_Dat_16(0x0203);
	Trans_Com_16(0x0032); Trans_Dat_16(0x0001);
	Trans_Com_16(0x0035); Trans_Dat_16(0x0205);
	Trans_Com_16(0x0036); Trans_Dat_16(0x030C);
	Trans_Com_16(0x0037); Trans_Dat_16(0x0607);
	Trans_Com_16(0x0038); Trans_Dat_16(0x0405);
	Trans_Com_16(0x0039); Trans_Dat_16(0x0707);
	Trans_Com_16(0x003C); Trans_Dat_16(0x0502);
	Trans_Com_16(0x003D); Trans_Dat_16(0x1008);
	//------------------ Set GRAM area ---------------//
	Trans_Com_16(0x0050); Trans_Dat_16(0x0000); // Horizontal GRAM Start Address
	Trans_Com_16(0x0051); Trans_Dat_16(0x00EF); // Horizontal GRAM End Address
	//Trans_Com_16(0x0051); Trans_Dat_16(0x000F); // Horizontal GRAM End Address
	Trans_Com_16(0x0052); Trans_Dat_16(0x0000); // Vertical GRAM Start Address
	Trans_Com_16(0x0053); Trans_Dat_16(0x013F); // Vertical GRAM End Address
	//Trans_Com_16(0x0053); Trans_Dat_16(0x000F); // Vertical GRAM End Address
	Trans_Com_16(0x0060); Trans_Dat_16(0xA700); // Gate Scan Line
	Trans_Com_16(0x0061); Trans_Dat_16(0x0001); // NDL,VLE); Trans_Dat_16(REV
	Trans_Com_16(0x006A); Trans_Dat_16(0x0000); // set scrolling line
	//-------------- Partial Display Control ---------//
	Trans_Com_16(0x0080); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0081); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0082); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0083); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0084); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0085); Trans_Dat_16(0x0000);
	//-------------- Panel Control -------------------//
	Trans_Com_16(0x0090); Trans_Dat_16(0x0010);
	Trans_Com_16(0x0092); Trans_Dat_16(0x0600);//0x0000
	Trans_Com_16(0x0093); Trans_Dat_16(0x0003);
	Trans_Com_16(0x0095); Trans_Dat_16(0x0110);
	Trans_Com_16(0x0097); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0098); Trans_Dat_16(0x0000);
	Trans_Com_16(0x0007); Trans_Dat_16(0x0133); // 262K color and display ON

	Trans_Com_16(0x0022);
}

//======Board Display======//
void Display(uint16_t c1,uint16_t x,uint16_t y)
 {
	uint16_t i,j;
	for(i=0;i<y;i++)
	 {
	 for(j=0;j<x;j++)
 	  {
	   Trans_Dat_16(c1);
	   }
	  }
 }

//=== Delay ms time define ===//
void Delayms(uint16_t i)
{
#if 0
	uint16_t j,k;
	for(j=0;j<i;j++)
	 for(k=0;k<200;k++);
#endif

	 delay32Ms(TIMER1,i);

}


void Delay(uint16_t i)
{
#if 0
	int j,k;
 	for(j=0;j<i;j++)
 	 for(k=0;k<8900;k++);
#endif

 	 delay32Ms(TIMER1,i*1000); //delay in second

}

